#include "RB-Tree.h"

#include <functional>

template <typename T>
struct identity
{
    constexpr T &&operator()(T &&t) const noexcept
    {
        return std::forward<T>(t);
    }

    constexpr const T &operator()(const T &t) const noexcept
    {
        return t;
    }

    T &&operator()(T &&t)
    {
        return std::forward<T>(t);
    }
};

int main()
{
    using int_rb_tree = rb_tree<int, int, identity<int>, std::less<int>>;
    rb_tree<int, int, identity<int>, std::less<int>> rbTree;
    rbTree.insert_unique(10);
    rbTree.insert_unique(7);
    rbTree.insert_unique(8);
    rbTree.insert_unique(15);
    rbTree.insert_unique(6);
    rbTree.insert_unique(11);
    rbTree.insert_unique(13);
    rbTree.insert_unique(12);

    auto iter = rbTree.find(10);

    using link_type = int_rb_tree::link_type;

    std::cout << "before erase size : " << rbTree.size() << std::endl;

    std::cout << "Traverse Tree Before Erase" << std::endl;

    for (
        int_rb_tree::iterator iter1 = rbTree.begin(),
                              iter2 = rbTree.end();
        iter1 != iter2; iter1++)
    {
        std::cout << *iter1 << std::endl;
    }

    rbTree.__erase_node((link_type)iter.node);

    std::cout << "After erase size : " << rbTree.size() << std::endl;

    for (
        int_rb_tree::iterator iter1 = rbTree.begin(),
                              iter2 = rbTree.end();
        iter1 != iter2; iter1++)
    {
        std::cout << *iter1 << std::endl;
    }
}